package main

import (
	"fmt"
	"reflect"
)

//专门演示反射
func reflectTest01(b interface{}) {
	//通过反射获取到传入的变量的type,kind,值
	//1 先获取到reflect.Type
	rType := reflect.TypeOf(b)
	fmt.Println("rType=", rType)

	//2 获取到reflect.Value
	rVal := reflect.ValueOf(b)
	// n2 := 2 + rVal  //这会报错 因为此时的rVal表面是100
	//但它是reflect.Value类型的数据 并不是int
	n2 := 2 + rVal.Int()
	fmt.Println("n2=", n2)
	fmt.Printf("rVal=%v  rVal=%T \n", rVal, rVal)

	//下面我们将rVal转成interface{}
	iV := rVal.Interface()
	//将interface{}通过断言转成需要的类型
	num2 := iV.(int)
	fmt.Println("num2=", num2)
}

func reflectTest02(b interface{}) {
	//通过反射获取到传入的变量的type,kind,值
	//1 先获取到reflect.Type
	rType := reflect.TypeOf(b)
	fmt.Println("rType=", rType)

	//2 获取到reflect.Value
	rVal := reflect.ValueOf(b)

	//3.获取变量对应的Kind
	//1 rVal.Kind*()
	kind1 := rVal.Kind()
	//2 rTyp.Kind()
	kind2 := rType.Kind()
	fmt.Printf("kind1=%v kind2=%v \n", kind1, kind2)

	//下面我们将rVal转成interface{}
	iV := rVal.Interface()
	fmt.Printf("iV=%v  iV type=%T \n", iV, iV)
	//将interface{}通过断言转成需要的类型
	//这里也可以用switch来优化
	stu, ok := iV.(Student)
	if ok {
		fmt.Printf("stu.Name=%v \n", stu.Name)
	}
}

type Student struct {
	Name string
	Age  int
}

func main() {

	//演示对（基本数据类型，interface{},reflect.Value）进行反射

	//1.先定义一个int
	var num int = 100
	reflectTest01(num)

	fmt.Println("-----------------------")

	//2.定义一个Student的实例
	stu := Student{
		Name: "tom",
		Age:  20,
	}
	reflectTest02(stu)
}
